import { Record, recordToString } from '../../salesforce';
import { Activity, Actor } from '@serenity-js/core';
import { UseSystem } from '../abilities';

export const createARecordOf = (objectName: string): CreateRecord => {
  return CreateRecord.ofType(objectName);
};

type RecordFields = {
  [key: string]: any;
};

export class CreateRecord implements Activity {
  private description: string;
  private additionalFields: { [key: string]: any };

  static ofType(objectType: string): CreateRecord {
    return new this(objectType);
  }

  private constructor(private readonly objectType: string) {}

  public async performAs(actor: Actor): Promise<any> {
    const useSystemAbility: UseSystem = actor.abilityTo(UseSystem);
    const salesforceApi = await useSystemAbility.salesforceApi();
    return salesforceApi.create(this.objectType, [this.constructRecord()]);
  }

  public toString(): string {
    return `#actor creates ${this.description || this.defaultDescription()}`;
  }

  public describedAs(customDescription: string): CreateRecord {
    this.description = customDescription;
    return this;
  }

  public withFields<T = RecordFields>(fields: T) {
    this.additionalFields = fields;
    return this;
  }

  private constructRecord(): Record {
    return {
      attributes: {
        type: this.objectType,
      },
      ...this.additionalFields,
    };
  }

  private defaultDescription() {
    return recordToString(this.constructRecord());
  }
}
